package com.example.gsp.mybatis.excutor;

import com.example.gsp.mybatis.config.Configuration;
import com.example.gsp.mybatis.config.MappedStatement;
import com.example.gsp.mybatis.util.ReflectionUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DefaultExcutor implements Excutor {

    private Configuration conf;

    public DefaultExcutor(Configuration conf) {
        this.conf = conf;
    }

    @Override
    public <E> List<E> query(MappedStatement ms, Object parameter) {

        List<E> resultList = new ArrayList<>();

        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;

        try {
            connection = DriverManager.getConnection(conf.getUrl(),conf.getUsername(),conf.getPassword());
            statement = connection.prepareStatement(ms.getSql());
            handlerParameter(statement,parameter);
            statement.execute();
            resultSet = statement.getResultSet();
            handlerResultSet(resultSet,resultList,ms.getResultType());
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return resultList;
    }

    private <E> void handlerResultSet(ResultSet resultSet, List<E> resultList,String className) {
        Class<E> clazz = null;
        try {
            clazz = ( Class<E>)Class.forName(className);
            while (resultSet.next()){
                E e = clazz.newInstance();
                ReflectionUtil.setResultSetToList(e,resultSet);
                resultList.add(e);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void handlerParameter(PreparedStatement statement, Object parameter) throws SQLException {
        if(parameter == null){
            return;
        }else if(parameter instanceof Integer){
            statement.setObject(0,parameter);
        }
    }
}
